/*
 * copyright (c) hisilicon technologies co., ltd. 2019-2026. all rights reserved.
 * description: thine_241a244_serdes.c
 * author: hisilicon multimedia software group
 * create: 2019-07-17
 */

#include "thine_241a244_serdes.h"

//#define DEBUG_AONI  // when run aoni serdes 244, need open  DEBUG_AONI

extern unsigned char serdes_init_flag[SERDES_MAX_NUM];

static inline void delay_us(const int us)
{
    udelay(us);
    return;
}

/* for 244 */
void write_serdes_rx_register(unsigned char i2c_dev, const unsigned int reg_addr, const unsigned int data)
{
    unsigned int reg_addr_num = 2;
    unsigned int data_byte_num = 1;
    unsigned char dev_addr = THINE_DEVICE_ADDR;

    serdes_i2c_write(i2c_dev, dev_addr, reg_addr, reg_addr_num, data, data_byte_num);

    return;
}

void write_serdes_rx_1bype_register(unsigned char i2c_dev, const unsigned int reg_addr, const unsigned int data)
{
    unsigned int reg_addr_num = 1;
    unsigned int data_byte_num = 1;
    unsigned char dev_addr = THINE_DEVICE_ADDR;

    serdes_i2c_write(i2c_dev, dev_addr, reg_addr, reg_addr_num, data, data_byte_num);

    return;
}

int read_serdes_rx_register(unsigned char i2c_dev, const unsigned int reg_addr)
{
    unsigned int r_data = 0;
    unsigned char dev_addr = (THINE_DEVICE_ADDR + 1);

    serdes_i2c_read(i2c_dev, dev_addr, reg_addr, &r_data);
    return r_data;
}

/* for 241A */
void write_serdes_tx_1bype_register(unsigned char i2c_dev, unsigned int reg_addr, const unsigned int data)
{
    unsigned int reg_addr_num = 1;
    unsigned int data_byte_num = 1;
    unsigned char dev_addr = (sensor_dev_addr[i2c_dev] << 1);

    serdes_i2c_write(i2c_dev, dev_addr, reg_addr, reg_addr_num, data, data_byte_num);
    return;
}

void write_serdes_tx_2bype_register(unsigned char i2c_dev, const unsigned int reg_addr, const unsigned int data)
{
    unsigned int reg_addr_num = 2;
    unsigned int data_byte_num = 1;
    unsigned char dev_addr = (sensor_dev_addr[i2c_dev] << 1);

    serdes_i2c_write(i2c_dev, dev_addr, reg_addr, reg_addr_num, data, data_byte_num);
    return;
}

void set_serdes_data_rate(unsigned char i2c_dev, serdes_mode_t serdes_mode)
{
    if (serdes_mode == SERDES_MODE_4LANE_LINEAR) {
        write_serdes_rx_register(i2c_dev, 0x1609, 0x00);

        write_serdes_rx_register(i2c_dev, 0x160A, 0x0C);

        write_serdes_rx_register(i2c_dev, 0x160B, 0x03);

        write_serdes_rx_register(i2c_dev, 0x160C, 0x01);

        write_serdes_rx_register(i2c_dev, 0x160D, 0x0C);

        write_serdes_rx_register(i2c_dev, 0x160E, 0x00);

        write_serdes_rx_register(i2c_dev, 0x160F, 0x01);

        write_serdes_rx_register(i2c_dev, 0x1610, 0x00);

        write_serdes_rx_register(i2c_dev, 0x1611, 0x02);

        write_serdes_rx_register(i2c_dev, 0x1612, 0x02);
    } else if ((serdes_mode == SERDES_MODE_2LANE_LINEAR) ||
               (serdes_mode == SERDES_MODE_4LANE_WDR)) {
        write_serdes_rx_register(i2c_dev, 0x1609, 0x03);

        write_serdes_rx_register(i2c_dev, 0x160A, 0x0F);

        write_serdes_rx_register(i2c_dev, 0x160B, 0x05);

        write_serdes_rx_register(i2c_dev, 0x160C, 0x01);

        write_serdes_rx_register(i2c_dev, 0x160D, 0x0A);

        write_serdes_rx_register(i2c_dev, 0x160E, 0x02);

        write_serdes_rx_register(i2c_dev, 0x160F, 0x02);

        write_serdes_rx_register(i2c_dev, 0x1610, 0x03);

        write_serdes_rx_register(i2c_dev, 0x1611, 0x02);

        write_serdes_rx_register(i2c_dev, 0x1612, 0x04);
    } else if (serdes_mode == SERDES_MODE_2LANE_WDR) {
        write_serdes_rx_register(i2c_dev, 0x1609, 0x04);

        write_serdes_rx_register(i2c_dev, 0x160A, 0x23);

        write_serdes_rx_register(i2c_dev, 0x160B, 0x08);

        write_serdes_rx_register(i2c_dev, 0x160C, 0x01);

        write_serdes_rx_register(i2c_dev, 0x160D, 0x11);

        write_serdes_rx_register(i2c_dev, 0x160E, 0x09);

        write_serdes_rx_register(i2c_dev, 0x160F, 0x06);

        write_serdes_rx_register(i2c_dev, 0x1610, 0x06);

        write_serdes_rx_register(i2c_dev, 0x1611, 0x10);

        write_serdes_rx_register(i2c_dev, 0x1612, 0x08);
    }
}

void get_serdes_cfg(serdes_mode_t serdes_mode, serdes_config *cfg)
{
    if (serdes_mode == SERDES_MODE_4LANE_LINEAR) {
        osal_memcpy(cfg, &imx307_4_lane_linear_12_bit_30_fps_cfg, sizeof(serdes_config));
    } else if (serdes_mode == SERDES_MODE_4LANE_WDR) {
        osal_memcpy(cfg, &imx307_4_lane_wdr_12_bit_30_fps_cfg, sizeof(serdes_config));
    } else if (serdes_mode == SERDES_MODE_2LANE_LINEAR) {
        osal_memcpy(cfg, &imx307_2_lane_linear_12_bit_30_fps_cfg, sizeof(serdes_config));
    } else {
        osal_memcpy(cfg, &imx307_2_lane_wdr_12_bit_30_fps_cfg, sizeof(serdes_config));
    }
}

/* connect SENSOR_RSTN's gpio_id */
void serdes_init_set_241a_gpio(unsigned char i2c_dev, unsigned int gpio_id)
{
    osal_printk("\n next is serdes_init_set_241a_gpio %d.\n", gpio_id);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0xFE, 0x21);
    if (gpio_id == 3) {
        write_serdes_tx_1bype_register(i2c_dev, 0x3E, 0x87);  // gpio3 -- output high
        write_serdes_tx_1bype_register(i2c_dev, 0x3F, 0x08);  // gpio3 -- cmos output
    } else if (gpio_id == 0) {
        write_serdes_tx_1bype_register(i2c_dev, 0x3E, 0x1E);  // gpio0 -- output high
        write_serdes_tx_1bype_register(i2c_dev, 0x3F, 0x08);  // gpio0 -- cmos output
        write_serdes_rx_register(i2c_dev, 0x0032, 0x10);
    }
    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);
}

void serdes_241a_244_lane0_init(unsigned char i2c_dev, serdes_mode_t serdes_mode)
{
    int i = 0;
    serdes_config cfg;

    osal_printk("\ni2c_dev%d, next is serdes_241a_244_lane0_init. \n", i2c_dev);

    get_serdes_cfg(serdes_mode, &cfg);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : THCV241A ID
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0050, 0x34);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : pass throuth mode
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0004, 0x03);

    /*---------------------------------------------------------
    step2: THCV244 sub link en/pol : lane 0 enable polling off
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x10); // polling off

    /*---------------------------------------------------------
    step3: THCV244 sub link power on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1704, 0x01);

    /*---------------------------------------------------------
    step4: THCV244 sub link tx term 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0102, 0x02); // 50ohm

    /*---------------------------------------------------------
    step5: THCV244 sub link tx drv 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0103, 0x02); // 12m_a

    /*---------------------------------------------------------
    step6: THCV244 sub link rx term : 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0104, 0x02); // 50ohm

    /*---------------------------------------------------------
    step7: THCV244 rx drv : 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0105, 0x02); // 12mA

    /*---------------------------------------------------------
    step8: THCV244 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0100, 0x03);

    /*---------------------------------------------------------
    step9: THCV244 reserved setting : key2 is unlocked
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010F, 0x25);

    /*---------------------------------------------------------
    step10: THCV244 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010A, 0x15); // 0x15 -> 0x18 -> 0x15

    write_serdes_rx_register(i2c_dev, 0x0031, 0x02);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    /*---------------------------------------------------------
    step13: THCV241 bank is 00
    ---------------------------------------------------------*/
    write_serdes_tx_2bype_register(i2c_dev, 0x00FE, 0x11);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x00);

    /*---------------------------------------------------------
    step14: THCV241 sub link tx term / drv setting:50ohm 12ma
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F2, 0x22); // 50ohm/12mA

    write_serdes_tx_1bype_register(i2c_dev, 0x00F3, 0x22); // 50ohm/12mA

    /*---------------------------------------------------------
    step15: THCV241 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F0, 0x03);

    /*---------------------------------------------------------
    THCV241 reserved setting : key 2 is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FF, 0x19);

    /*---------------------------------------------------------
    step16: THCV241 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F6, 0x18); // 0x15

    /*---------------------------------------------------------
    step16: THCV241 I2C freq   400k_hz
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00C9, 0x05);
    write_serdes_tx_1bype_register(i2c_dev, 0x00CA, 0x05);

    /*---------------------------------------------------------
    step17: THCV244 sub link en/pol : lane 0 enable polling on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x11);


    /*---------------------------------------------------------
    step18: THCV241 bank is 10
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);

    write_serdes_tx_1bype_register(i2c_dev, 0x0020, 0x0A); // Pre-emphasis/CML 0x0A 0x46 0x82

    write_serdes_tx_1bype_register(i2c_dev, 0x002C, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002D, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0076, 0x10);

    write_serdes_tx_1bype_register(i2c_dev, 0x0000, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0001, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x000F, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0011, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0012, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0013, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0014, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0015, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0016, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002B, 0x07);

    write_serdes_tx_1bype_register(i2c_dev, 0x002F, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x01);
    write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0027, 0x00);

    /*---------------------------------------------------------
    step19: THCV244
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1501, 0x00);

#ifdef DEBUG_AONI
    write_serdes_rx_register(i2c_dev, 0x1010, 0xA0);  // 0xA1 -> 0xA0 aoni

    write_serdes_rx_register(i2c_dev, 0x1011, 0x06);
#else
    write_serdes_rx_register(i2c_dev, 0x1010, 0xA1);
#endif

    write_serdes_rx_register(i2c_dev, 0x1021, 0x20);

    write_serdes_rx_register(i2c_dev, 0x1022, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1023, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1024, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1025, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1026, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1027, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1028, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1030, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1100, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1101, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1102, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1600, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x1602, 0xe4);  // 0x72 -> 0xe4

    write_serdes_rx_register(i2c_dev, 0x1603, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1605, cfg.pll_value[i]);

    write_serdes_rx_register(i2c_dev, 0x1606, 0x45);

    set_serdes_data_rate(i2c_dev, serdes_mode);

    write_serdes_rx_register(i2c_dev, 0x1704, 0x11);

    write_serdes_rx_register(i2c_dev, 0x1703, 0x01);

    /* GPIO setting */
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);
    write_serdes_tx_1bype_register(i2c_dev, 0x003D, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x003F, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x003E, 0x0E);
    delay_us(1000);
    write_serdes_tx_1bype_register(i2c_dev, 0x003E, 0x1E);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    write_serdes_rx_register(i2c_dev, 0x0040, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x0041, 0x1A);

#ifdef DEBUG_AONI
    serdes_init_set_241a_gpio(i2c_dev, 3);  // aoni need add
#endif

    return;
}

void serdes_241a_244_lane1_init(unsigned char i2c_dev, serdes_mode_t serdes_mode)
{
    int i = 0;
    serdes_config cfg;

    osal_printk("\n next is serdes_241a_244_lane1_init. \n");

    get_serdes_cfg(serdes_mode, &cfg);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : THCV241A ID
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0070, 0x34);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : pass throuth mode
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0004, 0x03);

    /*---------------------------------------------------------
    step2: THCV244 sub link en/pol : lane 0 enable polling off
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x20);

    /*---------------------------------------------------------
    step3: THCV244 sub link power on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1704, 0x02);

    /*---------------------------------------------------------
    step4: THCV244 sub link tx term 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0102, 0x08);

    /*---------------------------------------------------------
    step5: THCV244 sub link tx drv 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0103, 0x08);

    /*---------------------------------------------------------
    step6: THCV244 sub link rx term : 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0104, 0x08);

    /*---------------------------------------------------------
    step7: THCV244 rx drv : 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0105, 0x08);

    /*---------------------------------------------------------
    step8: THCV244 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0100, 0x03);

    /*---------------------------------------------------------
    step9: THCV244 reserved setting : key2 is unlocked
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010F, 0x25);

    /*---------------------------------------------------------
    step10: THCV244 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010A, 0x15);

    write_serdes_rx_register(i2c_dev, 0x0031, 0x02);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    /*---------------------------------------------------------
    step13: THCV241 bank is 00
    ---------------------------------------------------------*/
    write_serdes_tx_2bype_register(i2c_dev, 0x00FE, 0x11);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x00);

    /*---------------------------------------------------------
    step14: THCV241 sub link tx term / drv setting:50ohm 12ma
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F2, 0x22);
    write_serdes_tx_1bype_register(i2c_dev, 0x00F3, 0x22);

    /*---------------------------------------------------------
    step15: THCV241 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F0, 0x03);

    /*---------------------------------------------------------
    THCV241 reserved setting : key 2 is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FF, 0x19);

    /*---------------------------------------------------------
    step16: THCV241 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F6, 0x15);

    /*---------------------------------------------------------
    step16: THCV241 I2C freq   400k_hz
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00C9, 0x05);
    write_serdes_tx_1bype_register(i2c_dev, 0x00CA, 0x05);

    /*---------------------------------------------------------
    step17: THCV244 sub link en/pol : lane 0 enable polling on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x22);

    /*---------------------------------------------------------
    step18: THCV241 bank is 10
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);

    write_serdes_tx_1bype_register(i2c_dev, 0x002C, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002D, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0076, 0x10);

    write_serdes_tx_1bype_register(i2c_dev, 0x0000, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0001, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x000F, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0011, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0012, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0013, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0014, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0015, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0016, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002B, 0x06);

    write_serdes_tx_1bype_register(i2c_dev, 0x002F, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x01);
    write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0027, 0x00);

    /*---------------------------------------------------------
    step19: THCV244
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1501, 0x02);

    write_serdes_rx_register(i2c_dev, 0x1014, 0xA1);

    write_serdes_rx_register(i2c_dev, 0x1021, 0x20);

    write_serdes_rx_register(i2c_dev, 0x1022, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1023, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1024, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1025, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1026, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1027, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1028, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1030, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1200, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1201, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1202, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1600, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x1602, 0x72);

    write_serdes_rx_register(i2c_dev, 0x1603, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1605, cfg.pll_value[i]);

    write_serdes_rx_register(i2c_dev, 0x1606, 0x45);

    set_serdes_data_rate(i2c_dev, serdes_mode);

    write_serdes_rx_register(i2c_dev, 0x1704, 0x22);

    write_serdes_rx_register(i2c_dev, 0x1703, 0x01);

    /* GPIO setting */
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);
    write_serdes_tx_1bype_register(i2c_dev, 0x003D, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x003F, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x003E, 0x0E);
    delay_us(1000);
    write_serdes_tx_1bype_register(i2c_dev, 0x003E, 0x1E);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    write_serdes_rx_register(i2c_dev, 0x0060, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x0061, 0x1A);

#ifdef DEBUG_AONI
    serdes_init_set_241a_gpio(i2c_dev, 3);  // aoni need add
#endif

    return;
}

void serdes_241a_244_lane2_init(unsigned char i2c_dev, serdes_mode_t serdes_mode)
{
    int i = 0;
    serdes_config cfg;

    osal_printk("\n next is serdes_241a_244_lane2_init. \n");

    get_serdes_cfg(serdes_mode, &cfg);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : THCV241A ID
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0090, 0x34);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : pass throuth mode
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0004, 0x03);

    /*---------------------------------------------------------
    step2: THCV244 sub link en/pol : lane 0 enable polling off
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x40); // polling off

    /*---------------------------------------------------------
    step3: THCV244 sub link power on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1704, 0x04);

    /*---------------------------------------------------------
    step4: THCV244 sub link tx term 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0102, 0x20); // 50ohm

    /*---------------------------------------------------------
    step5: THCV244 sub link tx drv 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0103, 0x20); // 12m_a

    /*---------------------------------------------------------
    step6: THCV244 sub link rx term : 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0104, 0x20); // 50ohm

    /*---------------------------------------------------------
    step7: THCV244 rx drv : 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0105, 0x20); // 12mA

    /*---------------------------------------------------------
    step8: THCV244 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0100, 0x03);

    /*---------------------------------------------------------
    step9: THCV244 reserved setting : key2 is unlocked
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010F, 0x25);

    /*---------------------------------------------------------
    step10: THCV244 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010A, 0x15); // 0x15 -> 0x18 -> 0x15

    write_serdes_rx_register(i2c_dev, 0x0031, 0x02);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    /*---------------------------------------------------------
    step13: THCV241 bank is 00
    ---------------------------------------------------------*/
    write_serdes_tx_2bype_register(i2c_dev, 0x00FE, 0x11);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x00);

    /*---------------------------------------------------------
    step14: THCV241 sub link tx term / drv setting:50ohm 12ma
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F2, 0x22);
    write_serdes_tx_1bype_register(i2c_dev, 0x00F3, 0x22);

    /*---------------------------------------------------------
    step15: THCV241 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F0, 0x03);

    /*---------------------------------------------------------
    THCV241 reserved setting : key 2 is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FF, 0x19);

    /*---------------------------------------------------------
    step16: THCV241 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F6, 0x15);

    /*---------------------------------------------------------
    step16: THCV241 I2C freq   400k_hz
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00C9, 0x05);
    write_serdes_tx_1bype_register(i2c_dev, 0x00CA, 0x05);

    /*---------------------------------------------------------
    step17: THCV244 sub link en/pol : lane 0 enable polling on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x44);

    /*---------------------------------------------------------
    step18: THCV241 bank is 10
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);

    write_serdes_tx_1bype_register(i2c_dev, 0x002C, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002D, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0076, 0x10);

    write_serdes_tx_1bype_register(i2c_dev, 0x0000, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0001, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x000F, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0011, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0012, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0013, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0014, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0015, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0016, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002B, 0x06);

    write_serdes_tx_1bype_register(i2c_dev, 0x002F, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x01);
    write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0027, 0x00);

    /*---------------------------------------------------------
    step19: THCV244
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1501, 0x04);

    write_serdes_rx_register(i2c_dev, 0x1018, 0xA1);

    write_serdes_rx_register(i2c_dev, 0x1021, 0x20);

    write_serdes_rx_register(i2c_dev, 0x1022, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1023, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1024, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1025, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1026, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1027, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1028, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1030, 0x02);

    write_serdes_rx_register(i2c_dev, 0x1300, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1301, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1302, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1600, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x1602, 0x72);

    write_serdes_rx_register(i2c_dev, 0x1603, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1605, cfg.pll_value[i]);

    write_serdes_rx_register(i2c_dev, 0x1606, 0x45);

    set_serdes_data_rate(i2c_dev, serdes_mode);

    write_serdes_rx_register(i2c_dev, 0x1704, 0x44);

    write_serdes_rx_register(i2c_dev, 0x1703, 0x01);

    /* GPIO setting */
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);
    write_serdes_tx_1bype_register(i2c_dev, 0x003D, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x003F, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x003E, 0x0E);
    delay_us(1000);
    write_serdes_tx_1bype_register(i2c_dev, 0x003E, 0x1E);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    write_serdes_rx_register(i2c_dev, 0x0080, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x0081, 0x1A);

#ifdef DEBUG_AONI
    serdes_init_set_241a_gpio(i2c_dev, 3);  // aoni need add
#endif

    return;
}

void serdes_241a_244_lane3_init(unsigned char i2c_dev, serdes_mode_t serdes_mode)
{
    int i = 0;
    serdes_config cfg;

    osal_printk("\n next is serdes_241a_244_lane3_init. \n");

    get_serdes_cfg(serdes_mode, &cfg);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : THCV241A ID
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x00B0, 0x34);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : pass throuth mode
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0004, 0x03);

    /*---------------------------------------------------------
    step2: THCV244 sub link en/pol : lane 0 enable polling off
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x80); // polling off

    /*---------------------------------------------------------
    step3: THCV244 sub link power on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1704, 0x08);

    /*---------------------------------------------------------
    step4: THCV244 sub link tx term 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0102, 0x80); // 50ohm

    /*---------------------------------------------------------
    step5: THCV244 sub link tx drv 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0103, 0x80); // 12m_a

    /*---------------------------------------------------------
    step6: THCV244 sub link rx term : 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0104, 0x80); // 50ohm

    /*---------------------------------------------------------
    step7: THCV244 rx drv : 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0105, 0x80); // 12mA

    /*---------------------------------------------------------
    step8: THCV244 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0100, 0x03);

    /*---------------------------------------------------------
    step9: THCV244 reserved setting : key2 is unlocked
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010F, 0x25);

    /*---------------------------------------------------------
    step10: THCV244 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010A, 0x15);

    write_serdes_rx_register(i2c_dev, 0x0031, 0x02);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    /*---------------------------------------------------------
    step13: THCV241 bank is 00
    ---------------------------------------------------------*/
    write_serdes_tx_2bype_register(i2c_dev, 0x00FE, 0x11);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x00);

    /*---------------------------------------------------------
    step14: THCV241 sub link tx term / drv setting:50ohm 12ma
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F2, 0x22);
    write_serdes_tx_1bype_register(i2c_dev, 0x00F3, 0x22);

    /*---------------------------------------------------------
    step15: THCV241 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F0, 0x03);

    /*---------------------------------------------------------
    THCV241 reserved setting : key 2 is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FF, 0x19);

    /*---------------------------------------------------------
    step16: THCV241 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F6, 0x15);

    /*---------------------------------------------------------
    step16: THCV241 I2C freq   400k_hz
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00C9, 0x05);
    write_serdes_tx_1bype_register(i2c_dev, 0x00CA, 0x05);

    /*---------------------------------------------------------
    step17: THCV244 sub link en/pol : lane 0 enable polling on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x88);

    /*---------------------------------------------------------
    step18: THCV241 bank is 10
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);

    write_serdes_tx_1bype_register(i2c_dev, 0x002C, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002D, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0076, 0x10);

    write_serdes_tx_1bype_register(i2c_dev, 0x0000, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0001, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x000F, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0011, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0012, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0013, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0014, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0015, cfg.pll_value[i]);
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0016, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002B, 0x06);

    write_serdes_tx_1bype_register(i2c_dev, 0x002F, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x01);
    write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0027, 0x00);

    /*---------------------------------------------------------
    step19: THCV244
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1501, 0x06);

    write_serdes_rx_register(i2c_dev, 0x101C, 0xA1);

    write_serdes_rx_register(i2c_dev, 0x1021, 0x20);

    write_serdes_rx_register(i2c_dev, 0x1022, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1023, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1024, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1025, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1026, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1027, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1028, cfg.pll_value[i]);
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1030, 0x03);

    write_serdes_rx_register(i2c_dev, 0x1400, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1401, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1402, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1600, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x1602, 0x72);

    write_serdes_rx_register(i2c_dev, 0x1603, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1605, cfg.pll_value[i]);

    write_serdes_rx_register(i2c_dev, 0x1606, 0x45);

    set_serdes_data_rate(i2c_dev, serdes_mode);

    write_serdes_rx_register(i2c_dev, 0x1704, 0x88);

    write_serdes_rx_register(i2c_dev, 0x1703, 0x01);

    /* GPIO setting */
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);
    write_serdes_tx_1bype_register(i2c_dev, 0x003D, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x003F, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x003E, 0x0E);
    delay_us(1000);
    write_serdes_tx_1bype_register(i2c_dev, 0x003E, 0x1E);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    write_serdes_rx_register(i2c_dev, 0x00A0, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x00A1, 0x1A);

#ifdef DEBUG_AONI
    serdes_init_set_241a_gpio(i2c_dev, 3);  // aoni need add
#endif

    return;
}

void serdes_241a_244_lane0_1_init(unsigned char i2c_dev, serdes_mode_t serdes_mode)
{
    int i = 0;
    serdes_config cfg;

    osal_printk("\ni2c_dev%d, next is serdes_241a_244_lane0_1_init. \n", i2c_dev);

    get_serdes_cfg(serdes_mode, &cfg);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : THCV241A ID
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0050, 0x34);

    write_serdes_rx_register(i2c_dev, 0x0070, 0x34);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : pass throuth mode
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0004, 0x03);

    /*---------------------------------------------------------
    step2: THCV244 sub link en/pol : lane 0 enable polling off
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x30); // polling off

    /*---------------------------------------------------------
    step3: THCV244 sub link power on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1704, 0x03);

    /*---------------------------------------------------------
    step4: THCV244 sub link tx term 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0102, 0x0A);

    /*---------------------------------------------------------
    step5: THCV244 sub link tx drv 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0103, 0x0A);

    /*---------------------------------------------------------
    step6: THCV244 sub link rx term : 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0104, 0x0A);

    /*---------------------------------------------------------
    step7: THCV244 rx drv : 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0105, 0x0A);

    /*---------------------------------------------------------
    step8: THCV244 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0100, 0x03);

    /*---------------------------------------------------------
    step9: THCV244 reserved setting : key2 is unlocked
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010F, 0x25);

    /*---------------------------------------------------------
    step10: THCV244 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010A, 0x15);

    write_serdes_rx_register(i2c_dev, 0x0031, 0x02);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    /*---------------------------------------------------------
    step13: THCV241 bank is 00
    ---------------------------------------------------------*/
    write_serdes_tx_2bype_register(i2c_dev, 0x00FE, 0x11);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x00);

    /*---------------------------------------------------------
    step14: THCV241 sub link tx term / drv setting:50ohm 12ma
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F2, 0x22);
    write_serdes_tx_1bype_register(i2c_dev, 0x00F3, 0x22);

    /*---------------------------------------------------------
    step15: THCV241 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F0, 0x03);

    /*---------------------------------------------------------
    THCV241 reserved setting : key 2 is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FF, 0x19);

    /*---------------------------------------------------------
    step16: THCV241 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F6, 0x15);

    /*---------------------------------------------------------
    step16: THCV241 I2C freq   400k_hz
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00C9, 0x05);
    write_serdes_tx_1bype_register(i2c_dev, 0x00CA, 0x05);

    /*---------------------------------------------------------
    step17: THCV244 sub link en/pol : lane 0 enable polling on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0x33);

    /*---------------------------------------------------------
    step18: THCV241 bank is 10
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);

    write_serdes_tx_1bype_register(i2c_dev, 0x0020, 0x0A); // Pre-emphasis/CML 0x0A 0x46 0x82

    write_serdes_tx_1bype_register(i2c_dev, 0x002C, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002D, 0x11);  // cfg.pll_value[i] 0x11
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0076, 0x10);

    write_serdes_tx_1bype_register(i2c_dev, 0x0000, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0001, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x000F, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0011, 0x1B);  // cfg.pll_value[i] 0x1B
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0012, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0013, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0014, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0015, 0x66);  // cfg.pll_value[i] 0x66
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0016, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002B, 0x07);

    write_serdes_tx_1bype_register(i2c_dev, 0x002F, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x01);
    write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0027, 0x00);

    /*---------------------------------------------------------
    step19: THCV244
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1500, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1501, 0x00);

#ifdef DEBUG_AONI
    write_serdes_rx_register(i2c_dev, 0x1010, 0xA0);

    write_serdes_rx_register(i2c_dev, 0x1011, 0x06);

    write_serdes_rx_register(i2c_dev, 0x1014, 0xA0);

    write_serdes_rx_register(i2c_dev, 0x1015, 0x06);
#else
    write_serdes_rx_register(i2c_dev, 0x1010, 0xA1);

    write_serdes_rx_register(i2c_dev, 0x1014, 0xA1);
#endif

    write_serdes_rx_register(i2c_dev, 0x1021, 0x20);

    write_serdes_rx_register(i2c_dev, 0x1022, 0x01); // cfg.pll_value[i] 0x01
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1023, 0x11); // cfg.pll_value[i]  0x11
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1024, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1025, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1026, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1027, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1028, 0x02);  // cfg.pll_value[i]  0x02
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1030, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1100, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1200, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1101, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1201, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1102, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1202, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1600, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x1602, 0x72);

    write_serdes_rx_register(i2c_dev, 0x1603, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1605, 0x29);  // cfg.pll_value[i]  0x29

    write_serdes_rx_register(i2c_dev, 0x1606, 0x45);

    write_serdes_rx_register(i2c_dev, 0x1609, 0x00);

    write_serdes_rx_register(i2c_dev, 0x160A, 0x1D);

    write_serdes_rx_register(i2c_dev, 0x160B, 0x07);

    write_serdes_rx_register(i2c_dev, 0x160C, 0x02);

    write_serdes_rx_register(i2c_dev, 0x160D, 0x0C);

    write_serdes_rx_register(i2c_dev, 0x160E, 0x0B);

    write_serdes_rx_register(i2c_dev, 0x160F, 0x05);

    write_serdes_rx_register(i2c_dev, 0x1610, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1611, 0x10);

    write_serdes_rx_register(i2c_dev, 0x1612, 0x07);

    /* VC setting Lane0-VC0 Lane1-VC1 Lane2-VC2 Lane3-VC3 */
    write_serdes_rx_register(i2c_dev, 0x150B, 0xE4);
    write_serdes_rx_register(i2c_dev, 0x150C, 0xE5);
    write_serdes_rx_register(i2c_dev, 0x150D, 0xE6);
    write_serdes_rx_register(i2c_dev, 0x150E, 0xE7);

    write_serdes_rx_register(i2c_dev, 0x1704, 0x33);
    write_serdes_rx_register(i2c_dev, 0x1703, 0x01);
    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

#ifdef DEBUG_AONI
    serdes_init_set_241a_gpio(i2c_dev, 3);  // aoni is gpio3
#endif

    // Sub-link Lane0
    write_serdes_rx_register(i2c_dev, 0x0050, 0x34);
    write_serdes_rx_register(i2c_dev, 0x0040, 0x1A);
    write_serdes_rx_register(i2c_dev, 0x0041, 0x1A);

    // Sub-link Lane1
    write_serdes_rx_register(i2c_dev, 0x0070, 0x35);
    write_serdes_rx_register(i2c_dev, 0x0060, 0x1B);
    write_serdes_rx_register(i2c_dev, 0x0061, 0x1A);

    return;
}

void serdes_241a_244_lane2_3_init(unsigned char i2c_dev, serdes_mode_t serdes_mode)
{
    int i = 0;
    serdes_config cfg;

    osal_printk("\ni2c_dev%d, next is serdes_241a_244_lane2_3_init. \n", i2c_dev);

    get_serdes_cfg(serdes_mode, &cfg);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : THCV241A ID
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0090, 0x34);

    write_serdes_rx_register(i2c_dev, 0x00B0, 0x34);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : pass throuth mode
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0004, 0x03);

    /*---------------------------------------------------------
    step2: THCV244 sub link en/pol : lane 0 enable polling off
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0xC0); // polling off

    /*---------------------------------------------------------
    step3: THCV244 sub link power on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1704, 0x0C);

    /*---------------------------------------------------------
    step4: THCV244 sub link tx term 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0102, 0xA0); // 50ohm

    /*---------------------------------------------------------
    step5: THCV244 sub link tx drv 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0103, 0xA0); // 12m_a

    /*---------------------------------------------------------
    step6: THCV244 sub link rx term : 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0104, 0xA0); // 50ohm

    /*---------------------------------------------------------
    step7: THCV244 rx drv : 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0105, 0xA0); // 12mA

    /*---------------------------------------------------------
    step8: THCV244 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0100, 0x03);

    /*---------------------------------------------------------
    step9: THCV244 reserved setting : key2 is unlocked
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010F, 0x25);

    /*---------------------------------------------------------
    step10: THCV244 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010A, 0x15); // 0x15 -> 0x18 -> 0x15

    write_serdes_rx_register(i2c_dev, 0x0031, 0x02);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    /*---------------------------------------------------------
    step13: THCV241 bank is 00
    ---------------------------------------------------------*/
    write_serdes_tx_2bype_register(i2c_dev, 0x00FE, 0x11);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x00);

    /*---------------------------------------------------------
    step14: THCV241 sub link tx term / drv setting:50ohm 12ma
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F2, 0x22);
    write_serdes_tx_1bype_register(i2c_dev, 0x00F3, 0x22);

    /*---------------------------------------------------------
    step15: THCV241 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F0, 0x03);

    /*---------------------------------------------------------
    THCV241 reserved setting : key 2 is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FF, 0x19);

    /*---------------------------------------------------------
    step16: THCV241 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F6, 0x15);

    /*---------------------------------------------------------
    step16: THCV241 I2C freq   400k_hz
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00C9, 0x05);
    write_serdes_tx_1bype_register(i2c_dev, 0x00CA, 0x05);

    /*---------------------------------------------------------
    step17: THCV244 sub link en/pol : lane 0 enable polling on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0xCC);

    /*---------------------------------------------------------
    step18: THCV241 bank is 10
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);

    write_serdes_tx_1bype_register(i2c_dev, 0x0020, 0x0A); // Pre-emphasis/CML 0x0A 0x46 0x82

    write_serdes_tx_1bype_register(i2c_dev, 0x002C, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002D, 0x11);  // cfg.pll_value[i] 0x11
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0076, 0x10);

    write_serdes_tx_1bype_register(i2c_dev, 0x0000, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0001, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x000F, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0011, 0x1B);  // cfg.pll_value[i] 0x1B
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0012, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0013, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0014, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0015, 0x66);  // cfg.pll_value[i] 0x66
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0016, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002B, 0x06);

    write_serdes_tx_1bype_register(i2c_dev, 0x002F, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x01);
    write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0027, 0x00);

    /*---------------------------------------------------------
    step19: THCV244
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1500, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1501, 0x11);


#ifdef DEBUG_AONI
    write_serdes_rx_register(i2c_dev, 0x1018, 0xA0);
    write_serdes_rx_register(i2c_dev, 0x1019, 0x06);
    write_serdes_rx_register(i2c_dev, 0x101C, 0xA0);
    write_serdes_rx_register(i2c_dev, 0x101D, 0x06);
#else
    write_serdes_rx_register(i2c_dev, 0x1018, 0xA1);
    write_serdes_rx_register(i2c_dev, 0x101C, 0xA1);
#endif

    write_serdes_rx_register(i2c_dev, 0x1021, 0x20);
    write_serdes_rx_register(i2c_dev, 0x1022, 0x01); // cfg.pll_value[i] 0x01
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1023, 0x11); // cfg.pll_value[i]  0x11
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1024, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1025, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1026, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1027, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1028, 0x02);  // cfg.pll_value[i]  0x02
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1030, 0x02);

    write_serdes_rx_register(i2c_dev, 0x1300, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1400, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1301, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1401, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1302, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1402, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1600, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x1602, 0x72);

    write_serdes_rx_register(i2c_dev, 0x1603, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1605, 0x29);  // cfg.pll_value[i]  0x29

    write_serdes_rx_register(i2c_dev, 0x1606, 0x45);

    write_serdes_rx_register(i2c_dev, 0x1609, 0x00);

    write_serdes_rx_register(i2c_dev, 0x160A, 0x1D);

    write_serdes_rx_register(i2c_dev, 0x160B, 0x07);

    write_serdes_rx_register(i2c_dev, 0x160C, 0x02);

    write_serdes_rx_register(i2c_dev, 0x160D, 0x0C);

    write_serdes_rx_register(i2c_dev, 0x160E, 0x0B);

    write_serdes_rx_register(i2c_dev, 0x160F, 0x05);

    write_serdes_rx_register(i2c_dev, 0x1610, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1611, 0x10);

    write_serdes_rx_register(i2c_dev, 0x1612, 0x07);

    /* VC setting Lane0-VC0 Lane1-VC1 Lane2-VC2 Lane3-VC3 */
    write_serdes_rx_register(i2c_dev, 0x150B, 0xE6);
    write_serdes_rx_register(i2c_dev, 0x150C, 0xE7);
    write_serdes_rx_register(i2c_dev, 0x150D, 0xE4);
    write_serdes_rx_register(i2c_dev, 0x150E, 0xE5);

    write_serdes_rx_register(i2c_dev, 0x1704, 0xCC);
    write_serdes_rx_register(i2c_dev, 0x1703, 0x01);
    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

#ifdef DEBUG_AONI
    serdes_init_set_241a_gpio(i2c_dev, 3);  // aoni is gpio3
#endif

    // Sub-link Lane2
    write_serdes_rx_register(i2c_dev, 0x0090, 0x34);
    write_serdes_rx_register(i2c_dev, 0x0080, 0x1A);
    write_serdes_rx_register(i2c_dev, 0x0081, 0x1A);

    // Sub-link Lane3
    write_serdes_rx_register(i2c_dev, 0x00B0, 0x35);
    write_serdes_rx_register(i2c_dev, 0x00A0, 0x1B);
    write_serdes_rx_register(i2c_dev, 0x00A1, 0x1A);

    return;
}

void serdes_241a_244_2pt_2lane_init(unsigned char i2c_dev, serdes_mode_t serdes_mode)
{
    int i = 0;
    serdes_config cfg;

    osal_printk("\ni2c_dev%d, next is serdes_241a_244_2pt_2lane_init. \n", i2c_dev);

    get_serdes_cfg(serdes_mode, &cfg);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : THCV241A ID
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0050, 0x34);

    write_serdes_rx_register(i2c_dev, 0x0070, 0x34);

    write_serdes_rx_register(i2c_dev, 0x0090, 0x34);

    write_serdes_rx_register(i2c_dev, 0x00B0, 0x34);

    /*---------------------------------------------------------
    step1: THCV244 sub-link mode : pass throuth mode
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0004, 0x03);

    /*---------------------------------------------------------
    step2: THCV244 sub link en/pol : lane 0 enable polling off
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0xF0);

    /*---------------------------------------------------------
    step3: THCV244 sub link power on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1704, 0x0F);

    /*---------------------------------------------------------
    step4: THCV244 sub link tx term 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0102, 0xAA);

    /*---------------------------------------------------------
    step5: THCV244 sub link tx drv 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0103, 0xAA);

    /*---------------------------------------------------------
    step6: THCV244 sub link rx term : 50ohm
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0104, 0xAA);

    /*---------------------------------------------------------
    step7: THCV244 rx drv : 12ma
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0105, 0xAA);

    /*---------------------------------------------------------
    step8: THCV244 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0100, 0x03);

    /*---------------------------------------------------------
    step9: THCV244 reserved setting : key2 is unlocked
    ------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010F, 0x25);

    /*---------------------------------------------------------
    step10: THCV244 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x010A, 0x15);

    write_serdes_rx_register(i2c_dev, 0x0031, 0x02);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

    /*---------------------------------------------------------
    step13: THCV241 bank is 00
    ---------------------------------------------------------*/
    write_serdes_tx_2bype_register(i2c_dev, 0x00FE, 0x11);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x00);

    /*---------------------------------------------------------
    step14: THCV241 sub link tx term / drv setting:50ohm 12ma
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F2, 0x22);
    write_serdes_tx_1bype_register(i2c_dev, 0x00F3, 0x22);

    /*---------------------------------------------------------
    step15: THCV241 reserved setting : key is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F0, 0x03);

    /*---------------------------------------------------------
    THCV241 reserved setting : key 2 is unlocked
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FF, 0x19);

    /*---------------------------------------------------------
    step16: THCV241 reserved setting : sub link width
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00F6, 0x15);

    /*---------------------------------------------------------
    step16: THCV241 I2C freq   400k_hz
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00C9, 0x05);
    write_serdes_tx_1bype_register(i2c_dev, 0x00CA, 0x05);

    /*---------------------------------------------------------
    step17: THCV244 sub link en/pol : lane 0 enable polling on
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x0010, 0xFF);

    /*---------------------------------------------------------
    step18: THCV241 bank is 10
    ---------------------------------------------------------*/
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);

    write_serdes_tx_1bype_register(i2c_dev, 0x0020, 0x0A); // Pre-emphasis/CML 0x0A 0x46 0x82

    write_serdes_tx_1bype_register(i2c_dev, 0x002C, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002D, 0x11);  // cfg.pll_value[i] 0x11
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0076, 0x10);

    write_serdes_tx_1bype_register(i2c_dev, 0x0000, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0001, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x000F, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0011, 0x1B);  // cfg.pll_value[i] 0x1B
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0012, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0013, 0x00);
    write_serdes_tx_1bype_register(i2c_dev, 0x0014, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0015, 0x66);  // cfg.pll_value[i] 0x66
    i += 1;

    write_serdes_tx_1bype_register(i2c_dev, 0x0016, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x002B, 0x06);

    write_serdes_tx_1bype_register(i2c_dev, 0x002F, 0x00);

    write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x01);
    write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x01);

    write_serdes_tx_1bype_register(i2c_dev, 0x0027, 0x00);

    /*---------------------------------------------------------
    step19: THCV244
    ---------------------------------------------------------*/
    write_serdes_rx_register(i2c_dev, 0x1500, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1501, 0x15);  // 0x16 -> 0x15

#ifdef DEBUG_AONI
    write_serdes_rx_register(i2c_dev, 0x1010, 0xA0);
    write_serdes_rx_register(i2c_dev, 0x1011, 0x06);
    write_serdes_rx_register(i2c_dev, 0x1014, 0xA0);
    write_serdes_rx_register(i2c_dev, 0x1015, 0x06);
    write_serdes_rx_register(i2c_dev, 0x1018, 0xA0);
    write_serdes_rx_register(i2c_dev, 0x1019, 0x06);
    write_serdes_rx_register(i2c_dev, 0x101C, 0xA0);
    write_serdes_rx_register(i2c_dev, 0x101D, 0x06);
#else
    write_serdes_rx_register(i2c_dev, 0x1010, 0xA1);
    write_serdes_rx_register(i2c_dev, 0x1014, 0xA1);
    write_serdes_rx_register(i2c_dev, 0x1018, 0xA1);
    write_serdes_rx_register(i2c_dev, 0x101C, 0xA1);
#endif

    write_serdes_rx_register(i2c_dev, 0x1021, 0x20);

    write_serdes_rx_register(i2c_dev, 0x1022, 0x01); // cfg.pll_value[i] 0x01
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1023, 0x11); // cfg.pll_value[i] 0x11
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1024, 0x00);
    write_serdes_rx_register(i2c_dev, 0x1025, 0x00);
    write_serdes_rx_register(i2c_dev, 0x1026, 0x00);
    write_serdes_rx_register(i2c_dev, 0x1027, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1028, 0x00);  // cfg.pll_value[i]  0x02
    i += 1;

    write_serdes_rx_register(i2c_dev, 0x1030, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1100, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1200, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1300, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1400, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1101, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1201, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1301, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1401, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1102, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1202, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1302, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1402, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1600, 0x1A);

    write_serdes_rx_register(i2c_dev, 0x1602, 0x72);

    write_serdes_rx_register(i2c_dev, 0x1603, 0x02);

    write_serdes_rx_register(i2c_dev, 0x1605, 0x7D);  // cfg.pll_value[i]  0x29

    write_serdes_rx_register(i2c_dev, 0x1606, 0x4F);

    write_serdes_rx_register(i2c_dev, 0x1609, 0x00);

    write_serdes_rx_register(i2c_dev, 0x160A, 0x1D);

    write_serdes_rx_register(i2c_dev, 0x160B, 0x07);

    write_serdes_rx_register(i2c_dev, 0x160C, 0x02);

    write_serdes_rx_register(i2c_dev, 0x160D, 0x0C);

    write_serdes_rx_register(i2c_dev, 0x160E, 0x0B);

    write_serdes_rx_register(i2c_dev, 0x160F, 0x05);

    write_serdes_rx_register(i2c_dev, 0x1610, 0x01);

    write_serdes_rx_register(i2c_dev, 0x1611, 0x10);

    write_serdes_rx_register(i2c_dev, 0x1612, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1614, 0x00);

    write_serdes_rx_register(i2c_dev, 0x1615, 0x1D);

    write_serdes_rx_register(i2c_dev, 0x1616, 0x07);

    write_serdes_rx_register(i2c_dev, 0x1617, 0x02);

    write_serdes_rx_register(i2c_dev, 0x1618, 0x0C);

    write_serdes_rx_register(i2c_dev, 0x1619, 0x0B);

    write_serdes_rx_register(i2c_dev, 0x161A, 0x05);

    write_serdes_rx_register(i2c_dev, 0x161B, 0x01);

    write_serdes_rx_register(i2c_dev, 0x161C, 0x10);

    write_serdes_rx_register(i2c_dev, 0x161D, 0x07);

    write_serdes_rx_register(i2c_dev, 0x161F, 0x05);

    /* VC setting PT0 Lane0-VC0 Lane2-VC1,  PT1 Lane1-VC0 Lane3-VC1
     * 0xE4 -- only [1:0] available:  0 -- output VC0 on input VC0(all sensor is VC0)
     *                                1 -- output VC1 on input VC0(all sensor is VC0)
     */
    write_serdes_rx_register(i2c_dev, 0x150B, 0xE4);
    write_serdes_rx_register(i2c_dev, 0x150C, 0xE5);
    write_serdes_rx_register(i2c_dev, 0x150D, 0xE4);
    write_serdes_rx_register(i2c_dev, 0x150E, 0xE5);

    write_serdes_rx_register(i2c_dev, 0x1704, 0xFF);

    write_serdes_rx_register(i2c_dev, 0x1703, 0x01);

    write_serdes_rx_register(i2c_dev, 0x0032, 0x10);

#ifdef DEBUG_AONI
    serdes_init_set_241a_gpio(i2c_dev, 3);  // aoni is gpio3
#endif

    // Sub-link Lane0
    write_serdes_rx_register(i2c_dev, 0x0050, 0x34);
    write_serdes_rx_register(i2c_dev, 0x0040, 0x1A);
    write_serdes_rx_register(i2c_dev, 0x0041, 0x1A);

    // Sub-link Lane1
    write_serdes_rx_register(i2c_dev, 0x0070, 0x35);
    write_serdes_rx_register(i2c_dev, 0x0060, 0x1B);
    write_serdes_rx_register(i2c_dev, 0x0061, 0x1A);

    // Sub-link Lane2
    write_serdes_rx_register(i2c_dev, 0x0090, 0x36);
    write_serdes_rx_register(i2c_dev, 0x0080, 0x1C);
    write_serdes_rx_register(i2c_dev, 0x0081, 0x1A);

    // Sub-link Lane3
    write_serdes_rx_register(i2c_dev, 0x00B0, 0x37);
    write_serdes_rx_register(i2c_dev, 0x00A0, 0x1D);
    write_serdes_rx_register(i2c_dev, 0x00A1, 0x1A);

    return;
}


void serdes_244_reset(unsigned char i2c_dev)
{
    write_serdes_rx_register(i2c_dev, 0x1701, 0x3F);
    write_serdes_rx_register(i2c_dev, 0x1702, 0x01);  // SW reset
    write_serdes_rx_register(i2c_dev, 0x1703, 0x00);  // PLL power down
    write_serdes_rx_register(i2c_dev, 0x1704, 0x00);  // Vx1HS Sub-Link power down
    write_serdes_rx_register(i2c_dev, 0x0050, 0x34);
    write_serdes_rx_register(i2c_dev, 0x0004, 0x03);
    write_serdes_rx_register(i2c_dev, 0x0010, 0x10);
    write_serdes_rx_register(i2c_dev, 0x1704, 0x01);  // Vx1HS Sub-Link power on
    write_serdes_rx_register(i2c_dev, 0x0102, 0x02);
    write_serdes_rx_register(i2c_dev, 0x0103, 0x02);
    write_serdes_rx_register(i2c_dev, 0x0104, 0x02);
    write_serdes_rx_register(i2c_dev, 0x0105, 0x02);
    write_serdes_rx_register(i2c_dev, 0x0100, 0x03);
    write_serdes_rx_register(i2c_dev, 0x010F, 0x25);
    write_serdes_rx_register(i2c_dev, 0x010A, 0x15);
}

void serdes_241a_reset(unsigned char i2c_dev)
{
    write_serdes_rx_1bype_register(i2c_dev, 0x0031, 0x02);
    write_serdes_rx_1bype_register(i2c_dev, 0x0032, 0x00); // 1byte address, 1byte data access
    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21); // THCV241 bank is 10
    write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x00); // PLL Soft Reset Active
    write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x00); // Vx1HS Soft Reset Active
    write_serdes_tx_1bype_register(i2c_dev, 0x0021, 0x00); // MIPI Logic Reset
    write_serdes_tx_1bype_register(i2c_dev, 0x0022, 0x00); // Logic Reset
    write_serdes_tx_1bype_register(i2c_dev, 0x0023, 0x00); // MIPI Clock Reset

    delay_us(1000);

    write_serdes_tx_1bype_register(i2c_dev, 0x0021, 0x01); // MIPI Logic Reset
    write_serdes_tx_1bype_register(i2c_dev, 0x0022, 0x01); // Logic Reset
    write_serdes_tx_1bype_register(i2c_dev, 0x0023, 0x01); // MIPI Clock Reset

    write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x00);
}

void serdes_241a_244_exit(unsigned char i2c_dev)
{
    serdes_244_reset(i2c_dev);

    serdes_241a_reset(i2c_dev);
}

void serdes_thine_init(int i2c_dev, serdes_mode_t serdes_mode)
{
    serdes_241a_244_lane0_init(i2c_dev, serdes_mode);
    //serdes_241a_244_lane1_init(i2c_dev, serdes_mode);
    //serdes_241a_244_lane2_init(i2c_dev, serdes_mode);
    //serdes_241a_244_lane3_init(i2c_dev, serdes_mode);
    //serdes_241a_244_lane0_1_init(i2c_dev, serdes_mode);
    //serdes_241a_244_lane2_3_init(i2c_dev, serdes_mode);
    //serdes_241a_244_2pt_2lane_init(i2c_dev, serdes_mode);
}

void serdes_thine_exit(int i2c_dev)
{
    osal_printk("i2c_dev:%d, serdes_thine_exit\n", i2c_dev);
    serdes_241a_244_exit(i2c_dev);
}

void serdes_reset_unreset_sensor(unsigned char i2c_dev, int reset)
{
    if (serdes_init_flag[i2c_dev] == HI_TRUE) {
        const unsigned int tmp = reset ? 0x00 : 0x30;

        write_serdes_rx_register(i2c_dev, 0x0032, 0x00);
        write_serdes_tx_1bype_register(i2c_dev, 0xFE, 0x21);
        write_serdes_tx_1bype_register(i2c_dev, 0x3E, tmp);
        write_serdes_rx_register(i2c_dev, 0x0032, 0x10);
    }
}
EXPORT_SYMBOL(serdes_reset_unreset_sensor);

void serdes_enable_disable_sensor_clock(unsigned char i2c_dev, int enable)
{
    if (serdes_init_flag[i2c_dev] == HI_TRUE) {
        const unsigned int tmp = enable ? 0x10 : 0x50;

        write_serdes_rx_register(i2c_dev, 0x0032, 0x00);
        write_serdes_tx_1bype_register(i2c_dev, 0xFE, 0x21);
        write_serdes_tx_1bype_register(i2c_dev, 0x76, tmp);
        write_serdes_rx_register(i2c_dev, 0x0032, 0x10);
    }
}
EXPORT_SYMBOL(serdes_enable_disable_sensor_clock);
